public class code3 {
//    力扣 150 K个一组翻转链表
public ListNode reverseKGroup(ListNode head, int k) {
    // 这里直接通过局部修改的方式解决问题

    // 首先创建出一个新的头结点，因为头结点也是需要处理的范围
    ListNode newHead = new ListNode(-1);
    // 将新的头结点连接到 head 上
    newHead.next = head;
    ListNode p = newHead;

    // 通过 while 循环，解决局部反转的判定循环
    // 在后面的反转操作中， head 节点是需要进行后移的，在这里就可以作为判断条件
    while(head != null) {
        // 首先创建一个节点，找到 k 长度下的局部反转尾节点
        ListNode tail = p;
        for(int i = 0; i < k; i++) {
            tail = tail.next;
            // 当出现该节点指向 null 时，此时说明不符合题中 k 范围的反转条件
            if(tail == null) {
                // 此时直接返回新的头结点
                return newHead.next;
            }
        }
        // 以此 for 循环结束后，之后进行反转操作
        // 首先需要记录下新节点尾部链接的节点，便于之后反转成功后返回连接
        ListNode next = tail.next;
        // 这里创建一个 ListNode 类型的数组，用来记录返回的链表信息
        ListNode[] re = Reserve(head, tail);
        head = re[0];
        tail = re[1];
        // 之后将链表重新连接到原链表上
        p.next = head;
        tail.next = next;
        // 修改 p 的位置到新的
        p = tail;
        // 此时将 head 转移到新的起点进行下一次循环
        head = tail.next;
    }
    return newHead.next;
}

    // 实现链表反转方法
    private ListNode[] Reserve(ListNode head, ListNode tail) {
        // 创建一个新的节点，记录下这个链表的尾部位置的值便于反转操作
        ListNode pre = tail.next;
        // 创建一个节点记录 head 位置的节点
        ListNode p = head;
        while(pre != tail) {
            ListNode next = p.next;
            // 改变 p 节点的指向
            p.next = pre;
            // 让 pre 指向 p 要被改变的节点的位置
            pre = p;
            // 将 p 指向到下一个位置上
            p = next;
        }
        // 此时设定返回的数组，需要注意的是，这里返回的数组的头尾节点进行交换
        return new ListNode[]{tail, head};
    }
}
